﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using MS.InformationManagement.Support;
using MS.InformationManagement.Support.Constants;
using MS.InformationManagement.DAL.RecordCenter;
using MS.InformationManagement.DAL.DTOs;
using DAL = MS.InformationManagement.DAL;

namespace MS.InformationManagement.Core.RecordSiteQuery
{
    public class QueryRecordsSiteHelper<I>
        where I : Item
    {

        #region Properties

        #endregion

        #region Constructors


        #endregion

        /// <summary>
        /// Execute a query in the records sitecollection
        /// </summary>
        /// <param name="camlQuery">Query to be executed</param>
        /// <returns></returns>
        public static SPListItemCollection QueryRecordsSite(string list, string camlQuery, uint? rowLimit)
        {
            string recorsSiteUrl = ConfigurationHelper.GetInstance().ConfigItems[GlobalConstants.SITE_RECORDS_URL];
            using (SPSite recordsSite = new SPSite(recorsSiteUrl))
            {
                SPQuery query = new SPQuery() { Query = camlQuery };
                if (rowLimit.HasValue)
                    query.RowLimit = rowLimit.Value;
                return recordsSite.RootWeb.Lists[list].GetItems(query);
            }
        }

        /// <summary>
        /// Execute a query in the records sitecollection
        /// </summary>
        /// <typeparam name="I">Type entity to return</typeparam>
        /// <param name="list">List name</param>
        /// <param name="camlQuery">Query to be executed</param>
        /// <param name="rowLimit">Items to return</param>
        /// <returns>Collection of items founded</returns>
        public static IEnumerable<I> QueryRecordsAllEntitiesSite(string list, uint? rowLimit)
        {
            string recorsSiteUrl = ConfigurationHelper.GetInstance().ConfigItems[GlobalConstants.SITE_RECORDS_URL];
            using (SPSite recordsSite = new SPSite(recorsSiteUrl))
            {
                SPListItemCollection results = recordsSite.RootWeb.Lists[list].GetItems();
                return getEntities(results);
            }
        }

        /// <summary>
        /// Execute a query in the records sitecollection
        /// </summary>
        /// <typeparam name="I">Type entity to return</typeparam>
        /// <param name="list">List name</param>
        /// <param name="camlQuery">Query to be executed</param>
        /// <param name="rowLimit">Items to return</param>
        /// <returns>Collection of items founded</returns>
        public static IEnumerable<I> QueryRecordsEntitiesSite(string list, string camlQuery, uint? rowLimit)
        {
            SPListItemCollection results = null;
            string recorsSiteUrl = ConfigurationHelper.GetInstance().ConfigItems[GlobalConstants.SITE_RECORDS_URL];
            using (SPSite recordsSite = new SPSite(recorsSiteUrl))
            {
                SPQuery query = new SPQuery() { Query = camlQuery };
                if (rowLimit.HasValue)
                    query.RowLimit = rowLimit.Value;
                results = recordsSite.RootWeb.Lists[list].GetItems(query);
                return getEntities(results);
            }

        }

        public static I QueryRecordsParentEntitySite(string parentList, int parentId)
        {
            string recorsSiteUrl = ConfigurationHelper.GetInstance().ConfigItems[GlobalConstants.SITE_RECORDS_URL];
            using (SPSite recordsSite = new SPSite(recorsSiteUrl))
            {
                SPListItem item = DAL.Support.CamlHelper.GetParentItem(parentList, parentId, recordsSite.RootWeb);
                return getEntity(item);
            }
        }

        public static I QueryRecordsParentEntitySite(string parentList, int parentId, SPSite site)
        {
            SPListItem item = DAL.Support.CamlHelper.GetParentItem(parentList, parentId, site.RootWeb);
            return getEntity(item);
        }

        public static IEnumerable<I> QueryRecordsChildEntitiesSite(string childList, string parentId, string lookUpFieldName)
        {
            string recorsSiteUrl = ConfigurationHelper.GetInstance().ConfigItems[GlobalConstants.SITE_RECORDS_URL];
            using (SPSite recordsSite = new SPSite(recorsSiteUrl))
            {
                SPListItemCollection results = DAL.Support.CamlHelper.GetChildItemByParentId(lookUpFieldName, childList, parentId, recordsSite.RootWeb);
                return getEntities(results);
            }
        }

        public static IEnumerable<I> QueryRecordsChildEntitiesSite(string childList, string parentId, string lookUpFieldName, SPSite site)
        {
            SPListItemCollection results = DAL.Support.CamlHelper.GetChildItemByParentId(lookUpFieldName, childList, parentId, site.RootWeb);
            return getEntities(results);
        }

        public static I QueryRecordsEntityById(string list, int id, string siteUrl)
        {
            string recorsSiteUrl = ConfigurationHelper.GetInstance(siteUrl).ConfigItems[GlobalConstants.SITE_RECORDS_URL];
            using (SPSite recordsSite = new SPSite(recorsSiteUrl))
            {
                SPList targetList = recordsSite.RootWeb.Lists.TryGetList(list);
                if (targetList == null) { throw new Exception(string.Format("La lista {0} no existe o usted no tiene privilegios suficientes para acceder a ella", list)); }
                SPListItem results = id!=0? targetList.GetItemById(id): default(SPListItem);
                return getEntity(results);
            }
        }

        public static I QueryRecordsEntityById(string list, int id)
        {
            string recorsSiteUrl = ConfigurationHelper.GetInstance().ConfigItems[GlobalConstants.SITE_RECORDS_URL];
            using (SPSite recordsSite = new SPSite(recorsSiteUrl))
            {
                SPList targetList = recordsSite.RootWeb.Lists.TryGetList(list);
                if (targetList == null) { throw new Exception(string.Format("La lista {0} no existe o usted no tiene privilegios suficientes para acceder a ella", list)); }
                SPListItem results = id!=0? targetList.GetItemById(id): default(SPListItem);
                return getEntity(results);
            }
        }

        /// <summary>
        /// Execute a query in the records sitecollection
        /// </summary>
        /// <typeparam name="I">Type entity to return</typeparam>
        /// <param name="list">List name</param>
        /// <param name="rowLimit">Items to return</param>
        /// <returns>Collection of items founded</returns>
        public static IEnumerable<I> QueryAllRecords(string list, uint? rowLimit)
        {
            string recorsSiteUrl = ConfigurationHelper.GetInstance().ConfigItems[GlobalConstants.SITE_RECORDS_URL];
            using (SPSite recordsSite = new SPSite(recorsSiteUrl))
            {
                SPQuery query = new SPQuery();
                if (rowLimit.HasValue)
                    query.RowLimit = rowLimit.Value;
                SPListItemCollection results = recordsSite.RootWeb.Lists[list].GetItems();
                return getEntities(results);
            }
        }


        private static IEnumerable<I> getEntities(SPListItemCollection results)
        {
            if (typeof(I) == typeof(Seccion))
                return RecordsSiteDTO.GetCollection(results) as IEnumerable<I>;
            if (typeof(I) == typeof(Serie))
                return RecordsSiteDTO.GetCollectionSeries(results) as IEnumerable<I>;
            if (typeof(I) == typeof(Subseccion))
                return RecordsSiteDTO.GetCollectionSubSeccion(results) as IEnumerable<I>;
            if (typeof(I) == typeof(Subserie))
                return RecordsSiteDTO.GetCollectionSubSerie(results) as IEnumerable<I>;
            if (typeof(I) == typeof(ItemTRD))
                return RecordsSiteDTO.GetCollectionItemTRD(results) as IEnumerable<I>;
            if (typeof(I) == typeof(TipoDocumental))
                return RecordsSiteDTO.GetCollectionTipoDocumental(results) as IEnumerable<I>;
            return null;
        }


        private static I getEntity(SPListItem result)
        {
            if (result == null || result == default(SPListItem))
                return default(I);
            if (typeof(I) == typeof(Subseccion))
                return RecordsSiteDTO.GetSubSection(result) as I;
            if (typeof(I) == typeof(Subserie))
                return RecordsSiteDTO.GetSubSerie(result) as I;
            if (typeof(I) == typeof(Seccion))
                return RecordsSiteDTO.GetSeccion(result) as I;
            if (typeof(I) == typeof(Serie))
                return RecordsSiteDTO.GetSerieByItem(result) as I;
            if (typeof(I) == typeof(TipoDocumental))
                return RecordsSiteDTO.GetTipoDocumental(result) as I;
            return null;
        }

    }
}
